<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, reactive } from 'vue';
import { LocateSetData, TankBottomModelConfig } from '@/utils/appCommon/appCommonOptions/aeLocateConfigModel';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { computeScaleRate } from '@/views/apply/locateAnalysis/component/utils/commonThree';
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";

// 定义props接收父组件传递的参数
interface Props {
  locateSetting: LocateSetData | null;
  renderParams: {
    width: number;
    height: number;
    viewMode?: number;
  };
  searchParams: Record<string, any>;
}

const props = defineProps<Props>();

// Three.js核心对象
let scene: THREE.Scene | null = null;
let camera: THREE.PerspectiveCamera | null = null;
let renderer: THREE.WebGLRenderer | null = null;
let controls: OrbitControls | null = null;
let raycaster: THREE.Raycaster | null = null;
let mouse: THREE.Vector2 | null = null;

// 罐底相关对象
let tankBottomMesh: THREE.Mesh | null = null;
let tankBottomBorder: THREE.Mesh | null = null;
let gridMesh: THREE.GridHelper | null = null;
let axisLineMeshes: THREE.Object3D[] = [];
let axisTextMeshes: THREE.Object3D[] = [];

// 状态管理
const threeBoxRef = ref();
const threeData = reactive({
  width: 600,
  height: 600,
  bgColor: '#f0f4f8',
  compareSize: 200,
  scaleRate: 1
});

const mousePosition = reactive({
  x: 0,
  y: 0,
  angle: 0
});

// 传感器数据结构
const sensors = ref<Array<{id: number|string; x: number; y: number; z: number; angle: number; cube: THREE.Mesh; dynamicStyle: {left: string; top: string; display: string}}>>([]);

// 传感器编号计数器
let sensorCounter = 0;

// 防抖定时器
let resizeTimeout: NodeJS.Timeout | null = null;

// 初始化Three.js场景
function initThree() {
  try {
    if (!threeBoxRef.value || !props.locateSetting) return;

    // 清理之前的场景
    cleanup();

    // 创建新的场景
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera();
    renderer = new THREE.WebGLRenderer({ antialias: true });

    // 更新threeData的尺寸
    threeData.width = props.renderParams.width || 600;
    threeData.height = props.renderParams.height || 600;

    // 设置渲染器
    renderer.setSize(threeData.width, threeData.height);
    threeBoxRef.value.innerHTML = '';
    threeBoxRef.value.appendChild(renderer.domElement);

    // 设置背景色
    scene.background = new THREE.Color(threeData.bgColor);

    // 设置相机
    const cameraZ = threeData.width > 100 ? threeData.width : 100;
    camera.position.set(0, 0, cameraZ);
    camera.aspect = threeData.width / threeData.height;
    camera.updateProjectionMatrix();
    camera.lookAt(scene.position);

    // 创建轨道控制器
    controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    controls.enableRotate = true;
    controls.enablePan = true;
    controls.screenSpacePanning = false;
    controls.minDistance = 50;
    controls.maxDistance = 500;

    controls.addEventListener('change', () => {
      updateAllTextPosition();
    });

    // 添加光源
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(0, threeData.width, threeData.height);
    scene.add(light);

    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    // 创建辅助工具
    raycaster = new THREE.Raycaster();
    mouse = new THREE.Vector2();

    // 添加鼠标移动监听
    window.addEventListener('mousemove', listenMouseMove);
    // 初始化物体和坐标轴
    updateWidgets();

  } catch (error) {
    console.error('初始化Three.js场景失败:', error);
  }
}

function updateWidgets() {
  if (!scene) return;

  // 移除旧的罐底对象
  if (tankBottomMesh) {
    scene.remove(tankBottomMesh);
    tankBottomMesh.geometry.dispose();
    (tankBottomMesh.material as THREE.Material).dispose();
    tankBottomMesh = null;
  }

  if (tankBottomBorder) {
    scene.remove(tankBottomBorder);
    tankBottomBorder.geometry.dispose();
    (tankBottomBorder.material as THREE.Material).dispose();
    tankBottomBorder = null;
  }
  //创建坐标轴
  createAxis();
  // 创建新的罐底圆形
  createTankBottom();
  // 创建网格
  createGridXY()
}

// 处理鼠标移动 - 完全参考sphereFace3d.vue的实现方式
function listenMouseMove(event: MouseEvent) {
  if (!renderer || !camera || !scene || !raycaster || !mouse || !props.locateSetting) return;

  const rect = renderer.domElement.getBoundingClientRect();
  const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

  mouse.set(x, y);
  raycaster.setFromCamera(mouse, camera);

  // 使用光线投射器来获取与射线相交的物体
  const intersects = raycaster.intersectObjects(scene.children, true);
  if (intersects.length > 0) {
    const intersection = intersects[0];
    const position = intersection.point;

    // 应用缩放率并更新鼠标位置 - 注意这里是乘以scaleRate，与sphereFace3d.vue保持一致
    mousePosition.x = Number(position.x) * threeData.scaleRate;
    mousePosition.y = Number(position.y) * threeData.scaleRate;

    // 计算角度
    mousePosition.angle = Math.atan2(mousePosition.y, mousePosition.x) * (180 / Math.PI);
  }
}

// 添加传感器
function addSensor(x: number, y: number, angle: number = 0) {
  if (!scene) return;

  // 生成传感器ID
  const id = `sensor_${Date.now()}_${sensorCounter++}`;

  // 创建传感器几何体
  const geometry = new THREE.BoxGeometry(5 * threeData.scaleRate, 5 * threeData.scaleRate, 0.1);
  const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
  const cube = new THREE.Mesh(geometry, material);

  // 设置传感器位置（转换为世界坐标）
  cube.position.set(x * threeData.scaleRate, y * threeData.scaleRate, 0.1);
  scene.add(cube);

  // 创建传感器标签
  const label = createSimpleTextLabel(`S${sensorCounter}`);
  label.position.set(x * threeData.scaleRate, y * threeData.scaleRate + 8, 0.1);
  scene.add(label);

  // 将传感器添加到列表
  sensors.value.push({
    id,
    x,
    y,
    z: 0.1,
    angle,
    cube,
    dynamicStyle: { left: '0px', top: '0px', display: 'none' }
  });

  render();
}

// 删除传感器
function removeSensor(id: number|string) {
  if (!scene) return;

  const index = sensors.value.findIndex(sensor => sensor.id === id);
  if (index !== -1) {
    // 从场景中移除传感器立方体
    scene.remove(sensors.value[index].cube);
    // 从列表中移除
    sensors.value.splice(index, 1);
    render();
  }
}

// 清除所有传感器
function clearAllSensors() {
  if (!scene) return;

  // 从场景中移除所有传感器立方体
  sensors.value.forEach(sensor => {
    scene?.remove(sensor.cube);
  });
  // 清空列表
  sensors.value = [];
  render();
}

// 添加示例传感器数据
function addSampleSensors() {
  if (!props.locateSetting) return;

  const tankBottomConfig = props.locateSetting.config?.modelConfig as TankBottomModelConfig;
  const diameter = tankBottomConfig.tankBottomDiameter || 200;
  const sensorCount = tankBottomConfig.sensorCount || 4;

  const radius = diameter / 3; // 在罐底内部放置传感器
  const angleStep = (2 * Math.PI) / sensorCount;

  // 清除现有传感器
  clearAllSensors();

  // 添加示例传感器
  for (let i = 0; i < sensorCount; i++) {
    const angle = i * angleStep;
    const x = radius * Math.cos(angle);
    const y = radius * Math.sin(angle);
    addSensor(x, y, angle * (180 / Math.PI));
  }
}

// 更新传感器标签位置
function updateSensorsLabelPosition() {
  if (!camera || !renderer || !threeBoxRef.value) return;

  const rect = threeBoxRef.value.getBoundingClientRect();

  sensors.value.forEach(sensor => {
    if (!sensor.cube || !camera || !renderer) return;

    // 计算传感器在屏幕上的位置
    const position = new THREE.Vector3();
    sensor.cube.getWorldPosition(position);
    position.project(camera);

    // 转换为屏幕坐标
    const x = (position.x * 0.5 + 0.5) * rect.width;
    const y = (-position.y * 0.5 + 0.5) * rect.height;

    // 更新样式
    sensor.dynamicStyle.left = `${x}px`;
    sensor.dynamicStyle.top = `${y}px`;
    sensor.dynamicStyle.display = position.z < 1 ? 'block' : 'none';
  });
}

// 点击添加传感器
function handleAddSensorAtPosition() {
  addSensor(mousePosition.x, mousePosition.y, mousePosition.angle);
}

// 清理所有Three.js资源
function cleanup() {
  // 移除事件监听器
  window.removeEventListener('mousemove', listenMouseMove);

  // 清除定时器
  if (resizeTimeout) {
    clearTimeout(resizeTimeout);
    resizeTimeout = null;
  }
  // 清理场景中的对象
  if (scene) {
    // 移除罐底
    if (tankBottomMesh) {
      scene.remove(tankBottomMesh);
      tankBottomMesh.geometry.dispose();
      if ((tankBottomMesh.material as THREE.Material).dispose) {
        (tankBottomMesh.material as THREE.Material).dispose();
      }
      tankBottomMesh = null;
    }

    // 移除边框
    if (tankBottomBorder) {
      scene.remove(tankBottomBorder);
      tankBottomBorder.geometry.dispose();
      if ((tankBottomBorder.material as THREE.Material).dispose) {
        (tankBottomBorder.material as THREE.Material).dispose();
      }
      tankBottomBorder = null;
    }

    // 移除网格
    if (gridMesh) {
      scene.remove(gridMesh);
      gridMesh.geometry.dispose();
      if (Array.isArray(gridMesh.material)) {
        gridMesh.material.forEach(m => m.dispose());
      } else if (gridMesh.material && 'dispose' in gridMesh.material) {
        gridMesh.material.dispose();
      }
      gridMesh = null;
    }

    // 移除坐标轴和标签
    clearAxis();

    // 移除所有传感器
    clearAllSensors();

    // 移除控制器
    if (controls) {
      controls.dispose();
      controls = null;
    }
  }

  // 清理渲染器
  if (renderer) {
    renderer.dispose();
    renderer = null;
  }

  // 清理场景和相机
  scene = null;
  camera = null;
  raycaster = null;
  mouse = null;
}

// 监听locateSetting参数变化
watch(
  () => props.locateSetting,
  (newVal) => {
    console.log('定位设置变化:', newVal);
    if (newVal && threeBoxRef.value) {
      // 否则重新初始化
      cleanup();
      initThree();
    } else {
      cleanup();
    }
  },
  { deep: true, immediate: true }
);

// 监听renderParams参数变化
watch(
  () => props.renderParams,
  (newVal) => {
    console.log('渲染参数变化:', newVal);
    if (newVal && threeBoxRef.value) {
      threeData.width = newVal.width || 600;
      threeData.height = newVal.height || 600;

      if (renderer && camera) {
        renderer.setSize(threeData.width, threeData.height);
        camera.aspect = threeData.width / threeData.height;
        camera.updateProjectionMatrix();
        render();
      }
    }
  },
  { deep: true }
);

// 组件挂载时初始化
onMounted(() => {
  console.log('罐底定位组件挂载');
  if (props.locateSetting) {
    initThree();
  }
});

// 组件卸载时清理资源
onUnmounted(() => {
  console.log('罐底定位组件卸载，清理资源');
  cleanup();
})

// 渲染函数（带性能优化）
function render() {
  if (!renderer || !scene || !camera) return;

  try {
    renderer.render(scene, camera);
  } catch (error) {
    console.error('渲染失败:', error);
  }
}


// 获取罐底尺寸（考虑缩放）
function getDimensions(){
  const tankBottomConfig = props.locateSetting.config?.modelConfig as TankBottomModelConfig;
  const diameter = tankBottomConfig.tankBottomDiameter || 300;
  const xyRange = tankBottomConfig.xyRange || 300
  // 计算缩放率，使用最大尺寸作为基准
  const maxDimension = Math.max(diameter, xyRange);
  const scaleRate = computeScaleRate(maxDimension, 200); // 200作为比较尺寸
  threeData.scaleRate = scaleRate;
  // 转换为3D视图中的尺寸
  return {
    physicalXYRange: xyRange,
    physicalDiameter: diameter,
    xyRange: Math.max(xyRange / scaleRate, 1),
    diameter: Math.max(diameter / scaleRate, 1),
    scaleRate
  };
}

// 创建罐底圆形
function createTankBottom() {
  if (!scene || !props.locateSetting) return;
  if(tankBottomMesh){
    tankBottomMesh.removeFromParent()
  }
  const {xyRange,diameter} = getDimensions();

  // 创建圆形几何体
  const geometry = new THREE.CircleGeometry(diameter/2, 32);
  const material = new THREE.MeshBasicMaterial({
    color: 0xadd8e6,
    side:THREE.DoubleSide,
    transparent: true,
    opacity: 0.5
  });

  tankBottomMesh = new THREE.Mesh(geometry, material);
  tankBottomMesh.position.set(0,0,0)
  scene.add(tankBottomMesh);
}

// 创建XY网格和坐标轴
function createGridXY() {
  if (!scene || !props.locateSetting) return;
  if(gridMesh){
    gridMesh.removeFromParent()
  }
  const {xyRange,diameter} = getDimensions();
  // 创建网格辅助
  gridMesh = new THREE.GridHelper(
    xyRange * threeData.scaleRate,
    10,
    0xcccccc,
    0xeeeeee
  );
  gridMesh.rotation.x = Math.PI / 2;
  gridMesh.position.y = 0;
  gridMesh.position.x = 0;
  scene.add(gridMesh);
}

// 清理坐标轴
function clearAxis() {
  if (!scene) return;

  // 移除轴线
  axisLineMeshes.forEach(mesh => {
    if (mesh && scene) {
      scene.remove(mesh);
    }
  });
  axisLineMeshes = [];

  // 移除轴标签
  axisTextMeshes.forEach(mesh => {
    if (mesh && scene) {
      scene.remove(mesh);
    }
  });
  axisTextMeshes = [];
}

// 创建坐标轴 - 参考d3-bak.vue实现
function createAxis() {
  if (!scene) return;

  clearAxis()

  // 加载字体
  const fontLoader = new FontLoader();
  fontLoader.load('/public/threefont.json', function(font) {
    createAxisHelper(font);
  });
}

function createAxisHelper(font: any) {
  if (!scene) return;

  clearAxis()

  // 获取缩放后的尺寸
  const { xyRange } = getDimensions();
  const xRange = xyRange
  const yRange = xyRange
  const xhalf = xRange / 2;
  const yhalf = yRange / 2;

  // 创建材质
  const materialX = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色X轴
  const materialY = new THREE.LineBasicMaterial({ color: 0x00ff00 }); // 绿色Y轴
  const materialGridLine = new THREE.LineBasicMaterial({ color: 0xffffff });

  // 计算轴范围和步长
  const xstep = xRange / 10;
  const ystep = yRange / 10;

  // X轴刻度和标签
  for (let i = -xhalf; i <= xhalf; i += xstep) {
    // 创建网格线
    const geometry = new THREE.BufferGeometry();
    const positions = new Float32Array([0, 0, 0, 0, yRange, 0]);
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    const line = new THREE.Line(geometry, materialGridLine);
    axisLineMeshes.push(line);
    line.position.set(i, -yhalf, 0);
    scene.add(line);

    // 添加刻度标签（偶数位）- 参考d3-bak.vue的实现
    if (Math.abs(i + xhalf) % (2 * xstep) === 0) {
      const physicalValue = Math.round((i + xhalf) * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: xstep / 5,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(i - (xstep / 4), (-ystep / 2) - yhalf, 0.2);
      axisTextMeshes.push(textMesh);
      scene.add(textMesh);
    }
  }

  // Y轴刻度和标签
  for (let i = -yhalf; i <= yhalf; i += ystep) {
    // 创建网格线
    const geometry = new THREE.BufferGeometry();
    const positions = new Float32Array([0, 0, 0, xRange, 0, 0]);
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    const line = new THREE.Line(geometry, materialGridLine);
    axisLineMeshes.push(line);
    line.position.set(-xhalf, i, 0);
    scene.add(line);

    // 添加刻度标签（偶数位）- 参考d3-bak.vue的实现
    if (Math.abs(i + yhalf) % (2 * ystep) === 0) {
      const physicalValue = Math.round((i + yhalf) * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: ystep / 5,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(-xstep - xhalf, i, 0.2);
      axisTextMeshes.push(textMesh);
      scene.add(textMesh);
    }
  }

  // XYZ轴线
  // X轴
  const xAxisGeometry = new THREE.BufferGeometry();
  const xAxisPositions = new Float32Array([0, 0, 0, xRange, 0, 0]);
  xAxisGeometry.setAttribute('position', new THREE.BufferAttribute(xAxisPositions, 3));
  const xAxisLine = new THREE.Line(xAxisGeometry, materialX);
  xAxisLine.position.set(-xhalf, -yhalf, 0);
  axisLineMeshes.push(xAxisLine);
  scene.add(xAxisLine);

  // Y轴
  const yAxisGeometry = new THREE.BufferGeometry();
  const yAxisPositions = new Float32Array([0, 0, 0, 0, yRange, 0]);
  yAxisGeometry.setAttribute('position', new THREE.BufferAttribute(yAxisPositions, 3));
  const yAxisLine = new THREE.Line(yAxisGeometry, materialY);
  yAxisLine.position.set(-xhalf, -yhalf, 0);
  axisLineMeshes.push(yAxisLine);
  scene.add(yAxisLine);

  render();
}


// 创建简单的文本标签（使用几何体替代，实际项目中可能需要更复杂的文本渲染）
function createSimpleTextLabel(text: string) {
  const group = new THREE.Group();
  // 这里使用简单的几何体作为文本的占位符
  // 实际项目中应该使用Three.js的TextGeometry或CSS2DRenderer等
  const geometry = new THREE.BoxGeometry(6, 6, 0.1);
  const material = new THREE.MeshBasicMaterial({ color: 0x000000 });
  const cube = new THREE.Mesh(geometry, material);
  group.add(cube);
  return group;
}

// 更新所有文本位置
function updateAllTextPosition() {
  if (!camera || !renderer) return;

  // 确保文本始终面向相机
  axisTextMeshes.forEach(textMesh => {
    if (textMesh && camera) {
      textMesh.lookAt(camera.position);
      textMesh.rotation.x = 0; // 保持水平
      textMesh.rotation.z = 0;
    }
  });
  render()
}
</script>

<template>
  <div
    class="tank-bottom-container"
    :style="{
      width: `${renderParams.width}px`,
      height: `${renderParams.height}px`
    }"
  >
    <div class="title">
      鼠标: X={{ mousePosition.x.toFixed(1) }}mm, Y={{ mousePosition.y.toFixed(1) }}mm, 角度: {{ mousePosition.angle.toFixed(1) }}°
    </div>
    <div
      ref="threeBoxRef"
      class="three-container"
      @click="handleAddSensorAtPosition"
    ></div>
    <!-- 传感器编号显示 -->
    <template v-for="(sensor, index) in sensors" :key="sensor.id">
      <div class="sensor-label" :style="sensor.dynamicStyle">
        {{ sensor.id }}
      </div>
    </template>
  </div>
</template>

<style scoped lang="scss">
.tank-bottom-container {
  position: relative;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.title {
  position: relative;
  top: 0;
  left: 0;
  z-index: 100;
  width: 100%;
  text-align: center;
  font-size: 11px;
  background-color: transparent;
}

.three-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.sensor-label {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  display: inline-block;
  line-height: 1;
  color: orangered;
  font-size: 13px;
  pointer-events: none; /* 避免影响鼠标交互 */
}

:deep(canvas) {
  display: block;
  width: 100% !important;
  height: 100% !important;
}
</style>
